package com.lucifer.cloud.boot.blog.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lucifer.cloud.boot.blog.domin.bo.Star;
import com.lucifer.cloud.boot.blog.domin.type.BlogConstant;
import com.lucifer.cloud.boot.blog.domin.type.BlogStatusType;
import com.lucifer.cloud.boot.blog.domin.type.BlogType;
import com.lucifer.cloud.boot.blog.domin.type.CategoryType;
import com.lucifer.cloud.boot.blog.domin.bo.Blog;
import com.lucifer.cloud.boot.blog.domin.bo.Tag;
import com.lucifer.cloud.boot.blog.domin.bo.Upload;
import com.lucifer.cloud.boot.blog.domin.bo.User;
import com.lucifer.cloud.boot.blog.domin.dto.blog.BlogConverter;
import com.lucifer.cloud.boot.blog.domin.dto.blog.BlogInfo;
import com.lucifer.cloud.boot.blog.domin.dto.blog.BlogInfoDto;
import com.lucifer.cloud.boot.blog.domin.dto.blog.BlogReq;
import com.lucifer.cloud.boot.blog.domin.dto.tag.TagConverter;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserConverter;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserInfo;
import com.lucifer.cloud.boot.blog.mapper.BlogMapper;
import com.lucifer.cloud.boot.blog.mapper.TagMapper;
import com.lucifer.cloud.boot.blog.mapper.UploadMapper;
import com.lucifer.cloud.boot.blog.mapper.UserMapper;
import com.lucifer.cloud.boot.blog.service.BlogService;
import com.lucifer.cloud.boot.blog.config.UserSystem;
import com.lucifer.cloud.boot.blog.service.StarService;
import com.lucifer.cloud.commons.model.Result;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lucifer
 * @date 2023/12/21 15:24
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {


    @Resource
    private UserSystem userSystem;

    @Resource
    private UserMapper userMapper;

    @Resource
    private TagMapper tagMapper;

    @Resource
    private UploadMapper uploadMapper;

    @Resource
    private StarService starService;

    @Override
    public BlogInfoDto info(HttpServletRequest request, Long _t,String uid, Integer page, Integer limit,Integer category) {
        Long userId = userSystem.userId(request);
        User user = userMapper.selectById(userId);
        UserInfo user_info = UserConverter.convertInfo(user);
        List<Blog> blogList = Lists.newArrayList();
        Long count = 0L;
        if(Objects.isNull(page) && Objects.isNull(limit)){
            blogList = list(Wrappers.lambdaQuery(Blog.class)
                    .eq(Objects.nonNull(userId) && Objects.equals(CategoryType.MY.getIndex(), category), Blog::getUser_id, userId)
                    .eq(Objects.isNull(userId) || Objects.equals(CategoryType.RECOMMEND.getIndex(), category) ,Blog::getStatus, BlogStatusType.OPEN.getIndex())
                    .eq(StringUtils.isNotBlank(uid), Blog::getUid, uid)
            );
            count = blogList.stream().count();
        }else {
            Page<Blog> rowPage = new Page<>(page, limit);
            Page<Blog> blogPage = this.baseMapper.selectPage(rowPage, Wrappers.lambdaQuery(Blog.class)
                    .eq(Objects.nonNull(userId) && Objects.equals(CategoryType.MY.getIndex(), category),Blog::getUser_id, userId)
                    .eq(Objects.isNull(userId) || Objects.equals(CategoryType.RECOMMEND.getIndex(), category) ,Blog::getStatus, BlogStatusType.OPEN.getIndex())
                    .eq(StringUtils.isNotBlank(uid),Blog::getUid,uid));

            blogList = blogPage.getRecords();
            count = blogPage.getTotal();
        }
        List<User> userList = Lists.newArrayList();
        if(Objects.isNull(userId) || Objects.equals(CategoryType.RECOMMEND.getIndex(), category)){
            List<Long> userIdList = Optional.ofNullable(blogList).orElse(Lists.newArrayList())
                    .stream().map(Blog::getUser_id)
                    .collect(Collectors.toList());
            userList = userMapper.selectList(Wrappers.lambdaQuery(User.class).in(userIdList.size() > 0,User::getId, userIdList));
        }

        List<Star> starList = starService.list(Wrappers.lambdaQuery(Star.class)
                .eq(Objects.nonNull(userId),Star::getStar_id, uid)
                .eq(Star::getType, BlogType.BLOG.getIndex())
                .eq(Star::getStar_type,Boolean.TRUE)
        );
        List<String> star_ids = Optional.ofNullable(starList).orElse(Lists.newArrayList())
                .stream().map(Star::getUser_id)
                .map(String::valueOf)
                .collect(Collectors.toList());

        List<BlogInfo> blogInfoList = BlogConverter.convertList2InfoList(blogList, user_info,userList,category,star_ids);
        BlogInfoDto blogInfoDto = BlogInfoDto.builder().count(count).blog_info(blogInfoList).build();
        return blogInfoDto;
    }

    @Override
    public Result create(HttpServletRequest request, BlogReq blogReq) {
        Long userId = userSystem.userId(request);
        if(Objects.isNull(userId)){
           return Result.error(HttpStatus.UNAUTHORIZED.value(),BlogConstant.NOT_LOGIN);
        }
        Blog blog = BlogConverter.convertReq2blog(blogReq,userId);
        Tag tag = TagConverter.convertBlogReq2Tag(blogReq,userId);
        tagMapper.insert(tag);
        boolean save = save(blog);
        if(save){
            uploadMapper.update(new Upload(),Wrappers.lambdaUpdate(Upload.class)
                    .set(Upload::getBlog_id,blog.getUid())
                    .set(Upload::getUpdated_at,LocalDateTime.now())
                    .eq(Upload::getId,blogReq.getFile_id()));
        }
        return Result.success("博客创建成功",save);
    }

    @Override
    public Result update(HttpServletRequest request, BlogReq blogReq) {
        Long userId = userSystem.userId(request);
        if(Objects.isNull(userId)){
            return Result.error(HttpStatus.UNAUTHORIZED.value(),BlogConstant.NOT_LOGIN);
        }
        Blog blog = BlogConverter.convertReq2Eeditblog(blogReq);
        boolean update = update(Wrappers.lambdaUpdate(Blog.class)
                .set(Blog::getUpdated_at, LocalDateTime.now())
                .set(Blog::getTitle, blog.getTitle())
                .set(Blog::getSub_title, blog.getSub_title())
                .set(Blog::getContent, blog.getContent())
                .eq(Blog::getUid, blog.getUid())
        );
        return Result.success(update);
    }

    @Override
    public Result delete(HttpServletRequest request, String uid) {
        Long userId = userSystem.userId(request);
        if(Objects.isNull(userId)){
            return Result.error(HttpStatus.UNAUTHORIZED.value(),BlogConstant.NOT_LOGIN);
        }
        boolean remove = remove(Wrappers.lambdaQuery(Blog.class)
                .eq(Blog::getUid, Long.parseLong(uid))
                .eq(Objects.nonNull(userId),Blog::getUser_id, userId));
        if(remove){
            uploadMapper.delete(Wrappers.lambdaQuery(Upload.class).eq(Upload::getBlog_id,uid).eq(Objects.nonNull(userId),Upload::getUser_id,userId));
        }
        return Result.success(remove);
    }

}
